﻿using System;
using System.Configuration;
using System.IO;
using System.Security.Cryptography;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Reflection;

namespace WSMX_Invoice
{
    public partial class FunctionsTimbrado
    {
        /// <summary>
        /// Abre el archivo y devuelbe la cadena orginal del Elemento XML
        /// </summary>
        /// <param name="_comprobante">Path del archivo de la cadena Original</param>
        /// <returns>Cadena Original</returns>
        public static string GeneradorCadenas(string _filePath)
        {
            string result = "";

            if (String.IsNullOrEmpty(_filePath))
                throw new ArgumentNullException(_filePath);

            //Cargar el XML
            StreamReader reader = new StreamReader(_filePath);
            XPathDocument myXPathDoc = new XPathDocument(reader);

            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("WSMX_Invoice.MX.Invoice.version32.cadenaoriginal_3_2.xslt"))
            {
                using (XmlReader readerXML = XmlReader.Create(stream))
                {
                    //Cargando el XSLT
                    XslCompiledTransform myXslTrans = new XslCompiledTransform();
                    myXslTrans.Load(readerXML);
                    // use the XslTransform object

                    StringWriter str = new StringWriter();
                    XmlTextWriter myWriter = new XmlTextWriter(str);

                    //Aplicando transformacion
                    myXslTrans.Transform(myXPathDoc, null, myWriter);

                    //Resultado
                    result = str.ToString();
                }
            }

            //Fin del programa.
            return result;
        }

        /// <summary>
        /// Firma la cadena orginal para la obtencion del Sello Digial de la Factura
        /// </summary>
        /// <param name="_pathLlave">Ruta del sello digial CSD </param>
        /// <param name="_password">Contraseña del sello digital</param>
        /// <param name="_cadenaOriginal">Cadena original para genera el sello</param>
        /// <returns></returns>
        public static string getSello(string _pathLlave, string _password, string _cadenaOriginal)
        {
            string strSello = string.Empty;
            string strPathLlave = _pathLlave;
            string strLlavePwd = _password;
            string strCadenaOriginal = _cadenaOriginal; // Aquí ya haber generado la cadena original

            if (String.IsNullOrEmpty(_pathLlave))
                throw new ArgumentNullException(_pathLlave);

            if (String.IsNullOrEmpty(_password))
                throw new ArgumentNullException(_password);

            if (String.IsNullOrEmpty(_cadenaOriginal))
                throw new ArgumentNullException(_cadenaOriginal);


            System.Security.SecureString passwordSeguro = new System.Security.SecureString();
            passwordSeguro.Clear();
            foreach (char c in strLlavePwd.ToCharArray())
                passwordSeguro.AppendChar(c);

            byte[] llavePrivadaBytes = System.IO.File.ReadAllBytes(strPathLlave);

            RSACryptoServiceProvider rsa = WSMX_Invoice.Cripto.opensslkey.DecodeEncryptedPrivateKeyInfo(llavePrivadaBytes, passwordSeguro);
            SHA1CryptoServiceProvider hasher = new SHA1CryptoServiceProvider();

            byte[] bytesFirmados = rsa.SignData(System.Text.Encoding.UTF8.GetBytes(strCadenaOriginal), hasher);
            strSello = Convert.ToBase64String(bytesFirmados);  // Y aquí está el sello

            return strSello;
        }

    }
}
